// 函数类型
export default {}

// 1. 声明一个没有返回值的函数, 使用void来表示返回值为空。
function fn1(a:number,b:number):void{
  let sum: number = a + b;
  console.log(sum);  
}

// fn1(11,12,323) //应有 2 个参数，但获得 3 个。 调用函数时，不能少，不能多参数
// fn1(1) //  应有 2 个参数，但获得 1 个。

// 2. 有返回值的函数
function fn2(a:number,b:number):number{
  let sum: number = a + b;
  return sum
}

let s = fn2(1,2)
// console.log(s); //3

// 3. 可选择的参数, 在变量右边写个?,表示这个参数时可选择的参数。调用函数时，可以不传参数b.

function fn3(a:number, b?:number): number{
  if(b!== undefined ){
    return a + b;
  }else{
    return a;
  }
}

// s = fn3(10,20)
// console.log(s); // 30

// s = fn3(100)
// console.log(s); // 100


// 4. 有默认值的参数, 给参数b 初始值设置为0，如果传了b参数的值，就用传入的值赋值给b参数。如果没还有参数b的值传入，默认值就是0.
function fn4(a:number, b:number = 0){
  return a + b;
}

s = fn4(111,222)
console.log(s); // 333

s = fn4(1000)
console.log(s); // 1000

//5. 使用数组的解构来处理任意个参数：
function fn5(a:number, b:number, ...args: number[]):number{
 // args: [30,40,50]
  return args.reduce((sum, v)=>sum+v, 0) + a + b;
}

function fn6(...args:number[]):number{
  return args.reduce((sum, value)=>sum+value, 0);
}
console.log("sum:====", fn5(10,20,30,40,50)); // sum:==== 150
console.log("sum:====", fn6(10,20,30,40,50)); // sum:==== 150

// 6. 函数表达式：
// const 函数名：函数类型 = 函数
// 函数类型： （形式参数的类型）=>返回值类型
const fn7:  (...args:number[])=>number     =     function (...args:number[]):number{

  return args.reduce((sum, value)=>sum+value, 0);
}

const fn8: (...args:number[])=>number = (...args:number[]):number=>{return args.reduce((sum, value)=>sum+value, 0)}

// 7. 高阶函数：
// 所谓高阶函数： 一个函数，中另一个函数做参数，返回一个新的函数，这种函数叫高阶函数。
// 柯里化是指这样一个函数(假设叫做createCurry)，他接收函数A作为参数，运行后能够返回一个新的函数。并且这个新的函数能够处理函数A的剩余参数。


// 参数函数：
let args1: (a:number,b:number)=>number = function (a:number,b:number):number{
 return a+b;
}
// 高级函数
let HOFunction: ( fn: (...args: Array<number>)=>number )=>(...args: number[])=>void = function( fn: ( ...args:number[])=>number  ):(...args: number[])=>void {

  return function(...args:number[]){
    // 逻辑简单一点
    let temp = fn(args[0],args[1])
    console.log(temp);
  }
}

let newFunction = HOFunction(args1)
newFunction(10,20); // 30

/* 
//1 
let HOFunction = function(){
  return function(...args:number[]){
    let temp = fn(args[0],args[1])
    // ....
    console.log(temp);
    
  }
}

// 2. let HOFunction = function( 形参的函数类型 fn: (...args:number[])=> number){
  return function(...args:number[]){
  }
}
// 3. let HOFunction = function( fn: (...args:number[])=> number): 返回值的函数类型 (...args:number[])=>void  {
  return function(...args:number[]){
  }
}

//4
// 3. 
let HOFunction:  ( fn: (...args:number[])=> number  )   =>   (...args:number[])=>void 
= 
function( 形参 fn: (...args:number[])=> number   ): 函数返回值的类型 (...args:number[])=>void    
{
  return function(...args:number[]){
  }
}

let HOFunction: ( fn: (...args: Array<number>)=>number )=>(...args: number[])=>void = function( fn: ( ...args:number[])=>number  ):(...args: number[])=>void {

  return function(...args:number[]){
    let temp = fn(args[0],args[1])
    console.log(temp);
    
  }

} 
*/